#include "Channel.hpp"
#include <vector>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>



void Debug(vector<Channel>& channels)
{
    for(auto& e:channels)
        e.debug();
    return;
}


void Work(task_t work)
{
    work();
}
int main(int argc,char* argv[])
{
    //cout<<"hello world"<<endl;
    if(argc!=2)
    {
        cout<<"Usage "<<argv[0]<<" error"<<endl;
        cout<<"argc"<<" should"<<" be"<<": 2"<<endl;
    }
    //创建管道
    //确定管道的数量

    //vector来维护Channel
    vector<Channel> channels;
    int n = stoi(argv[1]);
    for(int i = 0;i<n;i++)
    {
        //创建管道
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        if(n<0)
        {
            return 1;
        }

        pid_t id = fork();
        if(id==0)
        {
            //子进程
            //r
            ::close(pipefd[1]);
            for(auto& e:channels)
            {
                ::close(e.Wfd());
            }
            while(true)
            {
                //char message[1024] = {0};
                char message[1024] = {0};
                int task_code = -1;
                int n = ::read(pipefd[0],&message,1024);
                task_code = stoi(message);
                cout<<task_code<<endl;
                if(n==0)
                {
                    break;
                }
                sleep(1);
                if(task_code)
                    Work(t.FindWork(task_code));
            }
            
            exit(0);

        }
        //父进程
        //w
        ::close(pipefd[0]);
        channels.emplace_back(pipefd[1],id);
    }
    //Debug(channels);
    //2.派发任务
    int count = 0;
    int cnt = 10;
    while(cnt--)
    {
        
        count%=n;
        cout<<"还剩余任务:"<<cnt<<endl;
        channels[count].debug();
        int task_code = t.Select();
        string task = to_string(task_code);
        ::write(channels[count].Wfd(),task.c_str(),sizeof(task_code));
        count++;
        sleep(1);
    }


    //退出进程池
    //version1
    // for(int i =  0;i<n;i++)
    // {
    //     ::close(channels[i].Wfd());
    //     cout<<channels[i].Name()<<"quit ..."<<endl;
    // }
    // for(int i = 0;i<n;i++)
    // {
        
    //     pid_t pid = ::waitpid(channels[i].Pid(),nullptr,0);
    //     if(pid>0)
    //     {
    //         cout<<channels[i].Name()<<"wait "<<channels[i].Pid()<<" success"<<endl;
    //     }
    // }
    //version2
    for(int i =  0;i<n;i++)
    {
        ::close(channels[i].Wfd());
        cout<<channels[i].Name()<<"quit ..."<<endl;
        pid_t pid = ::waitpid(channels[i].Pid(),nullptr,0);
        if(pid>0)
        {
            cout<<channels[i].Name()<<"wait "<<channels[i].Pid()<<" success"<<endl;
        }
    }
    return 0;
}